# !/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import json
import time
import copy
import time
import math#新加
import numpy as np
import pandas as pd
import datetime
from scipy.optimize import minimize
from scipy import linalg
from AssetAllocation.Common import *
from AssetAllocation import AssetsService
from AssetAllocation.TestBL import *


class BlackLitterman:
    def __init__(self,json_str):
        # 参数打包接收
        # self.json_str = kwargs.pop('json_str',None)
        self.json_str = json_str
        # print self.json_str
        # 解析参数
        self.business_info = self.json_str['business_info']#调用方信息 包括调用方代码 配置资产代码 对应指数代码等信息
        self.monthSpend = self.json_str['monthSpend']#月总支出 外部传参
        self.monthIncome = self.json_str['monthIncome']#月总收入
        self.Pmt = self.json_str['Pmt']#白条/金条当月应还总额
#         self.remain_amount = self.json_str['remain_amount']#白条/金条剩余额度 外部传参
        self.liabilityAsset = self.json_str['liabilityAsset']#负债率
        self.asset_investable = self.json_str['asset_investable']#用户可投资金  外部传参
        self.currentAsset=self.json_str['totalAssetAmt']#用户持仓金额 外部传参
        # self.insuranceAmt =  self.json_str['insuranceAmt']#保险账户建议金额
        self.fixAsset = self.json_str['fixAsset']#定期持仓总金额 默认default 0
        self.lambda_i = self.json_str['lambda_i']#换算得到的风评指标 外部传参
        self.mortagageAmt =self.json_str['mortagageAmt']
        self.liquidity =self.json_str['liquidity']
        self.upper_limits = self.json_str['upper_limits']# 新加 列表的列表  保守型用户和激进型用户在资产i上的上限 计算maxBoundCoefficients需要读取bl_param数据库 数据库需要相应修改 主程序有示例
        self.least_invest_amount = self.json_str['least_invest_amount']#新加 各资产最小投资金额 用于计算minBoundCoefficients 需要读取bl_param数据库 数据库需要相应修改 主程序有示例
        self.categoryLimitCoefficients = self.json_str['categoryLimitCoefficients']

#         self.interestPayment = self.json_str['interestPayment']#利息支出 默认default 0 非必须
        self.fluctuation = self.json_str['fluctuation']#波动率限制  默认default 非必须
#         self.lowerLimitSwitch = self.json_str['lowerLimitSwitch'] #资产下限控制开关 默认无下限归零限制
#         self.lowerLimitSwitchMatrix = self.json_str['lowerLimitSwitchMatrix'] #具体每个资产的开关矩阵
        # self.minBoundCtrlMatrix = np.array(self.json_str['lowerLimitSwitchMatrix']).T#有修改2
        self.minBoundCtrlMatrix = np.array(self.json_str['lowerLimitSwitchMatrix'])
#         self.productMissingMark = self.json_str['productMissingMark']# 大类产品缺失标志  默认均充足
        self.point_weightP = np.array(self.json_str['point_weightP'])#BL的P矩阵列求和 1*n的观点向量  默认读取BL参数数据表
        self.pointQ = np.array(self.json_str['pointQ']).T#BL的观点Q矩阵  默认读取BL参数数据表
        self.confidenceLC = self.json_str['confidenceLC']#观点信心水平向量 默认读取BL参数数据表
        self.lambda_mkt = self.json_str['lambda_mkt']#市场风险厌恶系数   默认读取BL参数数据表
        self.w0 = self.json_str['w0']#初始权重w0  默认根据传入的资产个数 等权
        self.omiga_mkt = self.json_str['omiga_mkt']#风险平价配置的资产配置原始比例
        self.minbounds = self.json_str['minbounds']#配置资产比例下限向量 默认0向量
        self.maxbounds = self.json_str['maxbounds']#配置资产比例上限向量 默认1向量
        self.tau_percent = np.array(self.json_str['historicalOdds']).mean()#平均信心水平 默认读取BL参数数据表或者缓存传入
        self.sigema = self.json_str['sigema']#资产收益协方差矩阵
        # self.maxBoundCoefficients = self.json_str['maxBoundCoefficients']#资产比例上限参数 迭代  由新输出参数与AsssetsService的get_maxBoundCoefficients得到
        # self.minBoundCoefficients = self.json_str['minBoundCoefficients']#资产比例下限参数 迭代 由新输出参数与AsssetsService的get_minBoundCoefficients得到
        self.num_assets = 5

    # 计算后验收益率期望
    def ER(self):
        lc_list = []
        for i in range(len(self.confidenceLC)):
            lc_list.append(1.0/self.confidenceLC[i])
        # 计算tau观点权重
        avg_Lc = float(sum(lc_list)/len(self.confidenceLC))
        # print 'tau_percent',self.tau_percent
        # print 'avg_lc',avg_Lc
        self.tao = self.tau_percent * 1.0/(avg_Lc)
        # self.tao = 1.0/(self.tau_percent*avg_Lc)
        # print 'tao',tao
        # 计算omega观点误差的协方差矩阵，是对角矩阵
        weightP_1 = np.array(self.point_weightP).sum(axis = 0)

        # print 'weightP_1',weightP_1
        tau_percent2 = np.mean(self.confidenceLC)
        CF  = tau_percent2*np.dot(np.dot(weightP_1,self.sigema),weightP_1.T)
        # print 'CF',CF
        for i in range(len(lc_list)):
            lc_list[i] = lc_list[i]*CF
        self.omega = np.diag(lc_list)

        pi = self.lambda_mkt * np.dot(self.sigema, np.array(self.omiga_mkt).T)  # n*1
        step_1 = linalg.inv(self.omega+self.tao*np.dot(np.dot(self.point_weightP,self.sigema),self.point_weightP.T))
        step_2 = (self.pointQ - np.dot(self.point_weightP,pi))
        # rs3 = self.pointQ - np.dot(self.point_weightP,pi) #K*1 k*1
        #计算后验收益期望 E[R] = pi + tao*segma*P.T(omega + tao*P*segma*P.T).I(Q - P*pi)
        res = pi + self.tao*np.dot(np.dot(np.dot(self.sigema,self.point_weightP.T),step_1),step_2)
        # print 'er',res
        return res

    # 目标函数
    def fun(self, w):
        ER_list = self.ER()
        sigma_bl = linalg.inv(linalg.inv(self.tao*np.array(self.sigema))+np.dot(np.dot(self.point_weightP.T,linalg.inv(np.array(self.omega))),self.point_weightP))

        fun = self.lambda_i / 2.0 * np.dot(np.dot(np.array(w).T, sigma_bl), np.array(w)) - np.dot(np.array(w).T, ER_list)
        # print 'flu', np.dot(np.dot(np.array(w), self.sigema), np.array(w).T)
        return fun

    # 约束条件--可投资产规模，对应配置资产个数约束
    def asset_cons(self,cons,bnds_min,bnds_max,minBoundsCtrlVector):
        # print bnds_min
        # print bnds_max
        # 受下限控制矩阵影响，导致资产上限之和小于1时
        # print(bnds_min)
        # print(bnds_max)
        # print(minBoundsCtrlVector)
        if sum(minBoundsCtrlVector) != len(minBoundsCtrlVector):
            CtrlVector_list = []
            _sum = 0
            bnds_max_valid_cnt = len([x for x in bnds_max if x != 0])
            for x in range(len(minBoundsCtrlVector)):
                if minBoundsCtrlVector[x] == 0:
                    CtrlVector_list.append(x)
            if len(CtrlVector_list) > 0:
                for _index in CtrlVector_list:
                    _sum += bnds_max[_index]
                    bnds_min[_index] = 0
                    bnds_max[_index] = 0
#                 print('bnds_max:',sum(bnds_max))
                if sum(bnds_max) < 1:
                    # print(bnds_max_valid_cnt)
                    # print(CtrlVector_list)
                    bnds_gain = _sum/float(bnds_max_valid_cnt-len(CtrlVector_list))
                    for x in range(len(minBoundsCtrlVector)):
                        if x not in CtrlVector_list and bnds_max[x] !=0:
                            bnds_max[x] = bnds_max[x] + bnds_gain

        # 每个资产上、下限 限制
        for i in range(len(self.w0)):
            # if bnds_max[i] > 0 and minBoundsCtrlVector[i] == 1:
            cons.append({'type': 'ineq', 'fun': lambda w,i=i: w[i] - bnds_min[i]})
            cons.append({'type': 'ineq', 'fun': lambda w,i=i: bnds_max[i] - w[i]})
            # else:
            #     cons.append({'type': 'eq', 'fun': lambda w,i=i: w[i]})

        return cons

    def constraint_list(self, minBoundsCtrlVector):
        # 投资比例相加等于1
        cons = [{'type': 'eq', 'fun': lambda w: sum(w) - 1},]
        # 组合方差小于给定的fluctuation
        if self.fluctuation != 'default':
            cons += [{'type': 'ineq', 'fun': lambda w: self.fluctuation - np.dot(np.dot(np.array(w),self.sigema), np.array(w).T)},]
        else:
            ## to do 组合小于等于2%波动率
            pass
#             cons = [{'type': 'leq', 'fun': lambda w: sum(w) - 1},]

        # 不同可投资产规模档位，对应配置资产个数限制
        # self.categoryLimits = AssetsService.get_categoryLimits(self.categoryLimitCoefficients,self.liquidity,self.monthIncome,self.Pmt,self.currentAsset,self.asset_investable,self.insuranceAmt,self.fixAsset)
        self.categoryLimits = AssetsService.get_categoryLimits(self.categoryLimitCoefficients, self.monthSpend,self.liquidity,
                                                               self.monthIncome, self.Pmt, self.currentAsset,
                                                               self.asset_investable, self.fixAsset)

        asset_investable,j_index = AssetsService.getInvestableAssets(self.lambda_i, self.asset_investable,self.categoryLimits,self.business_info)

        # 计算 minBoundCoefficients
        self.minBoundCoefficients = AssetsService.get_minBoundCoefficients(self.business_info,self.least_invest_amount)
        # lowWeight = AssetsService.getLowWeight(self.lambda_i, self.asset_investable, self.currentAsset, self.monthSpend, self.monthIncome, self.Pmt, self.liquidity,
        # self.fixAsset, self.insuranceAmt, self.business_info, self.minBoundCoefficients)
        lowWeight = AssetsService.getLowWeight(self.lambda_i, self.asset_investable, self.currentAsset, self.monthSpend, self.monthIncome, self.Pmt, self.liquidity,
        self.fixAsset, self.business_info, self.minBoundCoefficients)

        # 计算 maxBoundCoefficients
        self.maxBoundCoefficients = AssetsService.get_maxBoundCoefficients(self.business_info,self.upper_limits)
        highWeight = AssetsService.getHighWeight(lowWeight,self.lambda_i,self.maxBoundCoefficients)
        bnds_min, bnds_max = AssetsService.checkAndAdjustWeight(asset_investable, lowWeight, highWeight,self.business_info, self.lambda_i)
        cons = self.asset_cons(cons,bnds_min, bnds_max,minBoundsCtrlVector)

        # 大类资产下的指数约束
        categoryCodes = [x['categoryCode'][:3] for x in self.business_info]
        code_group_by = {}
        for k,v in enumerate(categoryCodes):
            if not code_group_by.get(v):
                code_group_by[v] = [k]
            else:
                code_group_by[v].append(k)
        code_group_by = sorted(code_group_by.items(), key=lambda x: x[1], reverse=False)

        # 组合的上下限限制 利率债+信用债等
        for k,v in code_group_by:
            # k:categoryCODE k:num
            if len(v) > 1:
                temp = []
                for i,j in enumerate(self.business_info):
                    if k in j['categoryCode']:
                        temp.append(i)
                if len(temp) == 2:
                    cons += [{'type': 'ineq', 'fun': lambda w,temp=temp: w[temp[0]] + w[temp[1]] - max(bnds_min[temp[0]],bnds_min[temp[1]])},]
                    cons += [{'type': 'ineq', 'fun': lambda w,temp=temp: max(bnds_max[temp[0]],bnds_max[temp[1]],max(bnds_min[temp[0]],bnds_min[temp[1]])) - (w[temp[0]] + w[temp[1]]) },]
                if len(temp) == 3:
                    cons += [{'type': 'ineq', 'fun': lambda w, temp=temp: w[temp[0]] + w[temp[1]]+ w[temp[2]] - max(bnds_min[temp[0]], bnds_min[temp[1]], bnds_min[temp[2]])}, ]
                    cons += [{'type': 'ineq', 'fun': lambda w, temp=temp: max(bnds_max[temp[0]], bnds_max[temp[1]], bnds_max[temp[2]],max(bnds_min[temp[0]], bnds_min[temp[1]], bnds_min[temp[2]])) - (w[temp[0]] + w[temp[1]]+ w[temp[2]])}, ]

        # 固收 + 债券组合上下限限制  有修改
        if set(['001','002']).issubset(set(categoryCodes)):
            temp = []
            for k in ['001','002']:
                for i, j in enumerate(self.business_info):
                    if k in j['categoryCode']:
                        temp.append(i)
            if len(temp) == 2:
                # cons += [{'type': 'ineq', 'fun': lambda w, temp=temp: w[temp[0]] + w[temp[1]] - float(self.interestPayment)/self.asset_investable}, ]
                #原固收+债券下限修改为：Min（Max{负债率，（房贷支出+当月账单待还额）/（用户持仓总金额+用户投资金额）}，固收上限+债券上限）
                cons += [{'type': 'ineq', 'fun': lambda w, temp=temp: w[temp[0]] + w[temp[1]] - min(bnds_max[temp[0]]+bnds_max[temp[1]],
                max(self.liabilityAsset,(self.mortagageAmt+self.Pmt)/(self.currentAsset+self.asset_investable)))}, ]

            if len(temp) == 3:
                #与上同理
                # cons += [{'type': 'ineq', 'fun': lambda w, temp=temp: w[temp[0]] + w[temp[1]] + w[temp[2]] - float(self.interestPayment) / self.asset_investable}, ]
                cons += [{'type': 'ineq', 'fun': lambda w, temp=temp: w[temp[0]] + w[temp[1]]+ w[temp[2]] - min(bnds_max[temp[0]] + max(bnds_max[temp[1]],bnds_max[temp[2]]),
                    max(self.liabilityAsset,(self.mortagageAmt + self.Pmt) / (self.currentAsset + self.asset_investable)))}, ]

        return cons,bnds_min,j_index

    def optimize2(self):
        bnds = np.array([self.minbounds,self.maxbounds]).T
        _init = True
        CtrlVector = [1] * len(self.w0)
        while True:
            cons, bnds_min, j = self.constraint_list(CtrlVector)
            sol = minimize(self.fun, self.w0, method='SLSQP', constraints=cons,bounds=bnds,tol=1e-15)
            # print(sol.x)
            rs = []
            for i in range(len(sol.x)):
                if sol.x[i]<1e-6:
                    rs.append(0.0) 
                else:
                    rs.append(round(sol.x[i],4))

            # 控制向量
            CtrlVector = list(self.minBoundCtrlMatrix[j])
            # 控制矩阵全为1，无需调整
            if (_init and sum(CtrlVector) == len(CtrlVector)) or not _init:
                return rs, sol.success
            # 控制矩阵存在调整项
            else:
                _init = False
                for x in range(len(CtrlVector)):
                    # 当出现控制矩阵元素为0的情况，满足触底归零条件
                    if CtrlVector[x] == 0:
                        # 资产配置比例未达到下限 或者 资产比例为零 则不用调整
                        if abs(rs[x] - bnds_min[x]) > 1e-2 or rs[x] == bnds_min[x] == 0:
                            CtrlVector[x] = 1
                if len(CtrlVector) == sum(CtrlVector):
                    return rs, sol.success

    def optimize(self):
        # 初始化资产权重
        w0 = np.ones(self.num_assets) * 1.0 / self.num_assets

        # bnds = np.array([self.minbounds, self.maxbounds]).T
        cons = [{'type': 'eq', 'fun': lambda x: np.sum(x) - 1}]
        #
        # bnds, instrument_type_cons = self._process_constraints()
        bnds = np.array([self.minbounds, self.maxbounds]).T
        # cons += instrument_type_cons
        opts = minimize(self.fun,
                        w0,
                        method='SLSQP',
                        bounds=bnds,
                        constraints=cons)
        # print(opts)
        return opts.x

# 随机序列，测试
def Test_With_Random_Data(json_str):
    #
    num_assets = 5
    num_obs = 100
    df_returns = Generate_Random_Data(num_assets, num_obs)
    print(df_returns)

    df_covariance = df_returns.cov() * 252
    covariance = df_covariance.values

    # sigema_omiga_mkt_data = AssetsService.update_var_local(business_info,recommendDate)
    # 更新json_str中的参数omiga,sigema
    # json_str.update(sigema_omiga_mkt_data)
    json_str.update({'sigema': df_covariance})
    json_str.update({'omiga_mkt': [0.2, 0.2, 0.2, 0.2, 0.2]})

    print("BL模型调用开始")
    bl = BlackLitterman(json_str=json_str)
    # bl.fun(json_str['w0'])
    resultData, resultCode = bl.optimize()
    print(resultData)


def Test_With_Real_Data(json_str, database):
    #
    datetiem1 = datetime.datetime(2017, 1, 1)
    datetiem2 = datetime.datetime(2020, 1, 1)
    symbols = ["AU.SHF", "H11001.CSI", "000300.SH", "SPX.GI", "000852.SH"]
    # symbols = ["000001.SH", "000300.SH"]
    return_profile = Load_Daily_Returns_DataFrame_Calc_Return_Volatility_Correlation(database,
                                                                                     symbol_list=symbols,
                                                                                     datetime1=datetiem1, datetime2=datetiem2,
                                                                                     is_log=False, annualized_days=252)
    covariance_matrix = return_profile["Covariance"]
    json_str.update({'sigema': covariance_matrix})
    json_str.update({'omiga_mkt': [0.2, 0.2, 0.2, 0.2, 0.2]})


    print("Return")
    print(return_profile["Returns"])
    print("Volatility")
    print(return_profile["Volatilities"])
    print("Correlation")
    print(return_profile["Correlation"])

    print("BL模型调用开始")
    bl = BlackLitterman(json_str=json_str)
    # bl.fun(json_str['w0'])
    resultData, resultCode = bl.optimize()
    print(resultData)


def Run_BL2():

    userParamJson = {
        'mortagageAmt': 0,  #
        'monthSpend': 0,  # 月总支出 外部传参
        'liquidity': 0,  # 流动性变动项mortgage + parents * 500 + children * 1000
        'Pmt': 0,  # 白条/金条当月应还总额
        'liabilityAsset': 0,  # 负债率
        'monthIncome': 0,  # 月总收入
        'asset_investable': 20000,  # 用户可投资金
        'totalAssetAmt': 0,  # 用户持仓金额
        'fixAsset': 0,  # 定期持仓总金额
        'lambda_i': lambda_user,  # 单位风险要求的收益报酬。换算得到的风评指标float(riskPrefer) 范围是2-7
        'upper_limits': [[1, 0.2], [0.6, 0.4], [0, 0.6], [0, 0.2], [0, 0.4]],
        'fluctuation': 'default',  # 风险约束  日波动率限制0.0000000004#
    }
    recommendDate = time.strftime('%Y-%m-%d', time.localtime(time.time()))
    userParamJson['recommendDate'] = recommendDate
    userParamJson['businessCode'] = "JD"

    system_params_data = {
        'minbounds': [0, 0, 0, 0, 0],
        'maxbounds': [1, 1, 1, 1, 1],
        'w0': [0.2, 0.2, 0.2, 0.2, 0.2],
        'lowerLimitSwitchMatrix': [[1, 1, 0, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]],
        # 资产开关矩阵
        'upper_limits': [[1, 0.2], [0.6, 0.4], [0, 0.6], [0, 0.2], [0, 0.4]],
        'least_invest_amount': [0, 0, 0, 0, 0],
        'lambda_mkt': 1,
        'categoryLimitCoefficients': [[-5000, 2000], [-4000, 3000], [-2000, 5000], [3000, 10000], [5000, 12000]],
        'business_info': [{'indexCode': 'I_CN6112_CNI', 'categoryCode': '001', 'order': 1},
                          {'indexCode': 'I_H11001_CSI', 'categoryCode': '002', 'order': 2},
                          {'indexCode': 'I_000300_SH', 'categoryCode': '003', 'order': 3},
                          {'indexCode': 'I_AUM', 'categoryCode': '004', 'order': 4},
                          {'indexCode': 'I_SPX_GI', 'categoryCode': '005', 'order': 5}],
        'point_weightP': view_weight_P,
        'confidenceLC': view_confidence,
        'pointQ': view_Q,
        'historicalOdds': tau_odds,
        'sigema': covariance_matrix,
        'omiga_mkt': market_weights
    }

    json_str = copy.deepcopy(system_params_data)
    json_str.update(userParamJson)  ##叠加用户参数，如果key相同则覆盖
    #
    # business_info = [{"categoryCode": "001", "indexCode": "I_CN6112_CNI", "order": 1},
    #                  {"categoryCode": "002", "indexCode": "I_H11001_CSI", "order": 2},
    #                  {"categoryCode": "003", "indexCode": "I_000300_SH", "order": 3},
    #                  {"categoryCode": "004", "indexCode": "I_AUM", "order": 4},
    #                  {"categoryCode": "005", "indexCode": "I_SPX_GI", "order": 5}]
    #
    # json_str["business_info"] = business_info

    bl = BL2.BlackLitterman(json_str=json_str)
    # bl.fun(json_str['w0'])
    resultData = bl.optimize()
    print(resultData)



if __name__ == '__main__':

    Run_BL2()

    # userParamJson = {
    #     'mortagageAmt': 0, #
    #     'monthSpend': 0,  # 月总支出 外部传参
    #     'liquidity': 0, # 流动性变动项mortgage + parents * 500 + children * 1000
    #     'Pmt': 0,  # 白条/金条当月应还总额
    #     'liabilityAsset': 0,  #负债率
    #     'monthIncome': 0,  # 月总收入
    #     'asset_investable': 20000,  # 用户可投资金
    #     'totalAssetAmt': 0,  # 用户持仓金额
    #     'fixAsset': 0,  # 定期持仓总金额
    #     'lambda_i': 6.5,  # 单位风险要求的收益报酬。换算得到的风评指标float(riskPrefer) 范围是2-7
    #     'upper_limits': [[1, 0.2], [0.6, 0.4], [0, 0.6], [0, 0.2], [0, 0.4]],
    #     'fluctuation': 'default',  # 风险约束  日波动率限制0.0000000004#
    # }
    # recommendDate = time.strftime('%Y-%m-%d', time.localtime(time.time()))
    # userParamJson['recommendDate']=recommendDate
    # userParamJson['businessCode'] = "JD"
    #
    # system_params_data = {
    #         'minbounds': [0, 0, 0, 0, 0],
    #         'maxbounds': [1, 1, 1, 1, 1],
    #        'w0': [0.2, 0.2, 0.2, 0.2, 0.2],
    #        'lowerLimitSwitchMatrix': [[1, 1, 0, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]],  # 资产开关矩阵
    #        'upper_limits': [[1, 0.2], [0.6, 0.4], [0, 0.6], [0, 0.2], [0, 0.4]],
    #        'least_invest_amount': [100, 200, 200, 200, 200],
    #        'lambda_mkt': 1,
    #        'categoryLimitCoefficients': [[-5000, 2000], [-4000, 3000], [-2000, 5000], [3000, 10000], [5000, 12000]],
    #        'business_info': [{'indexCode': 'I_CN6112_CNI', 'categoryCode': '001', 'order': 1}, {'indexCode': 'I_H11001_CSI', 'categoryCode': '002', 'order': 2}, {'indexCode': 'I_000300_SH', 'categoryCode': '003', 'order': 3}, {'indexCode': 'I_AUM', 'categoryCode': '004', 'order': 4}, {'indexCode': 'I_SPX_GI', 'categoryCode': '005', 'order': 5}],
    #        'point_weightP': [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]],
    #        'confidenceLC': [1.0, 0.6499263, 0.5139907, 0.5, 0.5479227],
    #        'pointQ': [5.56e-05, 0.0001288, 0.0003267, 0.0001519, 0.0003896],
    #        'historicalOdds': ([1, 0.89, 0.62, 0.56, 0.71],)
    #        }
    #
    # json_str = copy.deepcopy(system_params_data)
    # json_str.update(userParamJson) ##叠加用户参数，如果key相同则覆盖
    #
    # business_info= [{"categoryCode": "001","indexCode": "I_CN6112_CNI","order": 1},
    #             {"categoryCode": "002","indexCode": "I_H11001_CSI","order": 2},
    #             {"categoryCode": "003","indexCode": "I_000300_SH", "order": 3},
    #             {"categoryCode": "004","indexCode": "I_AUM","order": 4},
    #             {"categoryCode": "005","indexCode": "I_SPX_GI","order": 5}]
    #
    # json_str["business_info"] = business_info
    #
    # # Test_With_Random_Data(json_str)
    #
    # from Core.Config import *
    # pathfilename = os.getcwd() + "\..\Config\config2.json"
    # config = Config(pathfilename)
    # database = config.DataBase("JDMySQL")
    # Test_With_Real_Data(json_str, database)


